﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="SafDefinitionCache.cs" company="Collaboris Ltd.">
//   Copyright (c) Collaboris Ltd. All rights Reserved.
// </copyright>
// <summary>
//   
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Collaboris.Saf.Definitions
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;

    using Utilities;

    /// <summary>
    /// Action Definition Mgr is reponsible for providing
    /// Meta data information about all actions.
    /// </summary>
    [Serializable]
    public sealed class SafDefinitionCache
    {
        private SafDefinitionCache()
        {}

        private SafClassDefinitionCollection internalSafClassDefinitions;

        private ReadOnlyCollection<string> internalNamespaces;

        private SafClassDefinitionCollection InternalSafClassDefinitions
        {
            get
            {
                if (this.internalSafClassDefinitions == null)
                {
                    this.internalSafClassDefinitions = ActionReflector.GetActionDefinitionGraph();

                    foreach (KeyValuePair<string, SafClassDefinition> pair in internalSafClassDefinitions)
                    {
                        pair.Value.AssignParent(null);
                    }
                }
                return this.internalSafClassDefinitions;
            }
        }

        public static SafClassDefinitionCollection SafClassDefinitions
        {
            get
            {
                return Instance.InternalSafClassDefinitions;
            }
        }

        private ReadOnlyCollection<string> InternalSafNamespaces
        {
            get
            {
                if (this.internalNamespaces == null)
                {
                    List<string> allNamespaces = new List<string>();
                    foreach (KeyValuePair<string, SafClassDefinition> pair in SafClassDefinitions)
                    {
                        if (!allNamespaces.Contains(pair.Value.NameSpace))
                            allNamespaces.Add(pair.Value.NameSpace);

                    }

                    allNamespaces.Sort();
                    this.internalNamespaces = new ReadOnlyCollection<string>(allNamespaces);
                    
                }
                return this.internalNamespaces;
            }
        }

        public static ReadOnlyCollection<string> SafNamespaces
        {
            get
            {
                return Instance.InternalSafNamespaces;
            }
        }

        /// <summary>
        /// Gets only the namespaces that are in use!
        /// </summary>
        /// <value>The saf filtered namespaces.</value>
        public static ReadOnlyCollection<string> SafFilteredNamespaces
        {
            get
            {
                List<string> namespaces = new List<string>();

                foreach (string s in SafNamespaces)
                {
                    foreach (KeyValuePair<string, SafClassDefinition> pair in SafClassDefinitions)
                    {
                        if (pair.Value.NameSpace == s && pair.Value.IsAction)
                        {                            
                            namespaces.Add(s);
                            break;
                        }    
                    }
                    
                }

                namespaces.Sort();
                ReadOnlyCollection<string> filteredNames = new ReadOnlyCollection<string>(namespaces);
                
                return filteredNames;
            }
        }

        /// <summary>
        /// Gets only the namespaces that are in use!
        /// </summary>
        /// <value>The saf filtered namespaces.</value>
        public static ReadOnlyCollection<string> GetFilteredNamespacesByAssembly(string assemblyName)
        {
            
            List<string> namespaces = new List<string>();

            foreach (string s in SafNamespaces)
            {
                foreach (KeyValuePair<string, SafClassDefinition> pair in SafClassDefinitions)
                {
                    if (pair.Value.NameSpace == s 
                            && pair.Value.IsAction  
                            && pair.Value.AssemblyName.ToLower() == assemblyName.ToLower())
                    {
                        namespaces.Add(s);
                        break;
                    }
                }

            }

            namespaces.Sort();
            ReadOnlyCollection<string> filteredNames = new ReadOnlyCollection<string>(namespaces);

            return filteredNames;
            
        }



        /// <summary>
        /// Gets the a singleton.
        /// </summary>
        /// <value>The instance.</value>
        public static SafDefinitionCache Instance
        {
            get
            {
                return Nested.instance;
            }
        }

        class Nested
        {
            // Explicit static constructor to tell C# compiler
            // not to mark type as beforefieldinit
            static Nested()
            {
            }

            internal static readonly SafDefinitionCache instance = new SafDefinitionCache();

        }
    }
}